

#include "ipconnection.h"

IpConnection::IpConnection(ClientThread *cth) :
    aborted(false),
    mutex(QMutex::Recursive),
    uploaded(0),
    downloaded(0)
{
    _ip = cth->ip();
    pushBack(cth);
}


IpConnection::~IpConnection()
{
    qWarning() << __FUNCTION__;
    if(threads.size() > 0){
        qWarning() << "Delete IpConnection when has threads!!!";
    }
}


void IpConnection::abort(bool wait_closed, bool lock)
{
    QVector <ClientThread *>::iterator it;
    do
    {
        if(lock) mutex.lock();
        it = threads.begin();
        if(it == threads.end()) {
            if(lock) mutex.unlock();
            break;
        }

        (*it)->abort();
        if(wait_closed)
            (*it)->waitForFinished();

        if(it == threads.end()) {
            if(lock) mutex.unlock();
            break;
        }

        it++;
        if(lock) mutex.unlock();
    }while(it != threads.end());

}


void IpConnection::forceAbort(bool wait_closed, bool lock)
{
    if(aborted) return;

    qWarning() << __FUNCTION__;

    QVector <ClientThread *>::iterator it;
    do
    {
        if(lock) mutex.lock();
        it = threads.begin();
        if(it == threads.end()) {
            if(lock) mutex.unlock();
            break;
        }

        (*it)->force_abort();
        if(wait_closed)
            (*it)->waitForFinished();

        if(it == threads.end()) {
            if(lock) mutex.unlock();
            break;
        }

        it++;
        if(lock) mutex.unlock();
    }while(it != threads.end());

    aborted = true;
    qWarning() << __FUNCTION__ << "end";
}


void IpConnection::pushBack(ClientThread *cth)
{
    QMutexLocker locker(&mutex);


    if(threads.indexOf(cth) > -1) {
        qWarning() << __FUNCTION__ << "push_back() thread already exist!";
        return;
    }

    threads.push_back(cth);

    //connect(cth, SIGNAL(clientThreadDestroyed(ClientThread*)), this, SLOT(threadDisconnected(ClientThread*)));
}


int IpConnection::erase(ClientThread *cth)
{
    QMutexLocker locker(&mutex);

    int i = threads.indexOf(cth);

    if(i < 0) {
        qWarning() << __FUNCTION__ << "erase() thread not exist!";
        return -1;
    }

    qWarning() << "thread: " << i;
    //disconnect(cth, SIGNAL(clientThreadDestroyed(ClientThread*)), this, SLOT(threadDisconnected(ClientThread*)));
    threadDisconnected(cth);
    threads.remove(i);
    return 0;
}



QStringList IpConnection::threadsObjectList()
{
    QMutexLocker locker(&mutex);

    QStringList list;

    foreach(ClientThread *thread, threads)
    {
        QString obj = thread->downloadingObject();
        if(!obj.isEmpty())
            list << obj;
    }

    return list;
}


quint64 IpConnection::threadsTotalUpload(bool lock)
{
    if(lock)
        QMutexLocker locker(&mutex);

    quint64 size = uploaded;

    foreach(ClientThread *thread, threads) {
        size += thread->totalUploaded();
    }

    return size;
}


quint64 IpConnection::threadsTotalDownload(bool lock)
{
    if(lock)
        QMutexLocker locker(&mutex);

    quint64 size = downloaded;

    foreach(ClientThread *thread, threads) {
        size += thread->totalDownloaded();
    }

    return size;
}


quint64 IpConnection::threadsUploadSpeed(bool lock)
{
    if(lock)
        QMutexLocker locker(&mutex);

    quint64 size = 0;

    foreach(ClientThread *thread, threads) {
        size += thread->currentUploadSpeed();
    }

    return size;
}


quint64 IpConnection::threadsDownloadSpeed(bool lock)
{
    if(lock)
        QMutexLocker locker(&mutex);

    quint64 size = 0;

    foreach(ClientThread *thread, threads) {
        size += thread->currentDownloadSpeed();
    }

    return size;
}


void IpConnection::threadDisconnected(ClientThread *thread)
{
    uploaded += thread->totalUploaded();
    downloaded += thread->totalDownloaded();
}

